From: kaf24@firebug.cl.cam.ac.uk Date: Tue, 10 Jan 2006 17:53:44 +0000 (+0100) Subject: Update map_domain_page() documentation (mappings may only be X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~16541^2~69 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=8aa806e0b1bd15ac97bcd43d77f46be5c03e07ff;p=xen.git Update map_domain_page() documentation (mappings may only be be used within the mapping vcpu). Implement TLB flush filtering on the per-domain mapcache. Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/x86_32/domain_page.c b/xen/arch/x86/x86_32/domain_page.c index 8b28103cf8..b8ca0ab47d 100644 --- a/xen/arch/x86/x86_32/domain_page.c +++ b/xen/arch/x86/x86_32/domain_page.c @@ -40,7 +40,8 @@ void *map_domain_pages(unsigned long pfn, unsigned int order) { unsigned long va; unsigned int idx, i, flags, vcpu = current->vcpu_id; - struct mapcache *cache = ¤t->domain->arch.mapcache; + struct domain *d; + struct mapcache *cache; #ifndef NDEBUG unsigned int flush_count = 0; #endif @@ -49,17 +50,24 @@ void *map_domain_pages(unsigned long pfn, unsigned int order) perfc_incrc(map_domain_page_count); /* If we are the idle domain, ensure that we run on our own page tables. */ - if ( unlikely(is_idle_vcpu(current)) ) + d = current->domain; + if ( unlikely(is_idle_domain(d)) ) __sync_lazy_execstate(); + cache = &d->arch.mapcache; + spin_lock(&cache->lock); /* Has some other CPU caused a wrap? We must flush if so. */ - if ( cache->epoch != cache->shadow_epoch[vcpu] ) + if ( unlikely(cache->epoch != cache->shadow_epoch[vcpu]) ) { - perfc_incrc(domain_page_tlb_flush); - local_flush_tlb(); cache->shadow_epoch[vcpu] = cache->epoch; + if ( NEED_FLUSH(tlbflush_time[smp_processor_id()], + cache->tlbflush_timestamp) ) + { + perfc_incrc(domain_page_tlb_flush); + local_flush_tlb(); + } } do { @@ -71,6 +79,7 @@ void *map_domain_pages(unsigned long pfn, unsigned int order) perfc_incrc(domain_page_tlb_flush); local_flush_tlb(); cache->shadow_epoch[vcpu] = ++cache->epoch; + cache->tlbflush_timestamp = tlbflush_current_time(); } flags = 0; diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 0a29f61b1c..b9955c0249 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -17,6 +17,7 @@ struct mapcache { l1_pgentry_t *l1tab; unsigned int cursor; unsigned int epoch, shadow_epoch[MAX_VIRT_CPUS]; + u32 tlbflush_timestamp; spinlock_t lock; }; diff --git a/xen/include/xen/domain_page.h b/xen/include/xen/domain_page.h index 8e0a524a42..8fbd9ffaa7 100644 --- a/xen/include/xen/domain_page.h +++ b/xen/include/xen/domain_page.h @@ -17,21 +17,21 @@ /* * Maps a given range of page frames, returning the mapped virtual address. The - * pages are now accessible within the current domain until a corresponding + * pages are now accessible within the current VCPU until a corresponding * call to unmap_domain_page(). */ extern void *map_domain_pages(unsigned long pfn, unsigned int order); /* * Pass a VA within the first page of a range previously mapped in the context - * of the currently-executing domain via a call to map_domain_pages(). Those + * of the currently-executing VCPU via a call to map_domain_pages(). Those * pages will then be removed from the mapping lists. */ extern void unmap_domain_pages(void *va, unsigned int order); /* * Similar to the above calls, except the mapping is accessible in all - * address spaces (not just within the domain that created the mapping). Global + * address spaces (not just within the VCPU that created the mapping). Global * mappings can also be unmapped from any context. */ extern void *map_domain_page_global(unsigned long pfn);